/*
* Copyright (c) 2007 by Kirill Kolodyazhniy.
* See the file "license.terms" for information on usage and redistribution.
*/

#ifndef M_DXRENDERWINDOW_H
#define M_DXRENDERWINDOW_H

#include "dxheaders.h"

#include "renderwindow.h"
#include "dxglobals.h"

namespace Engine
{

	class DXRenderWindowInfo: public RenderWindowInfo
	{
	public:
		DXRenderWindowInfo(HWND hwnd):m_hWnd(hwnd){}
		void Accept(RenderWindowInfoVisitor& visitor){visitor.Visit(this);}
		HWND GetHWND()const {return m_hWnd;}
	private:
		HWND m_hWnd;
	};

	/**
	*   Direct3D window.
	*/
	class DXRenderWindow: public RenderWindow
	{
		friend class DXRenderSystem;
		friend class DXBuffersVisitor;
	public:

		/**
		*   Destructor.
		*/
		~DXRenderWindow();

		/**
		*   Swaps the frame buffers to display the next frame.
		*/
		virtual void SwapBuffers();

		/**
		*   Creates & displays the new window
		*/
		virtual void Create(const std::string& name, const PresentParams& pp);

		/**
		*   Visitor implementation.
		*/
		virtual void Accept(RenderTargetVisitor& visitor);

		/**
		*   Return Direct3D presentation parameters.
		*/
		void GetPresentationParameters(D3DPRESENT_PARAMETERS* params);

		/**
		*   Get system specific window id.
		*/
		virtual	RefPtr<RenderWindowInfo> GetID();

		/**
		*   Return list of available screen resolutions for this window.
		*/
		virtual Resolutions GetAvailableResolutions() const;

		/**
		*   Set new resolution
		*/
		virtual void SetResolution(unsigned int width, unsigned int height);

		/**
		*   Return list of available antialiasing modes(MSAA) for this window.
		*/
		virtual FSAAModes GetAvailableFSAAModes() const;

		/**
		*   Set new antialiasing mode.
		*/
		virtual void SetFSAAMode(unsigned int mode);

		/**
		*   Get current fsaa mode.
		*/
		virtual unsigned int GetFSAAMode();

		/**
		*   Return buffers width.
		*/
		virtual unsigned int GetBufferWidth();

		/**
		*   Return buffers height.
		*/
		virtual unsigned int GetBufferHeight();

		/**
		*   Set fullscreen mode.
		*/
		virtual void SetFullScreen(bool val);

		/**
		*   Return true if in fullscreen mode.
		*/
		virtual bool IsFullScreen();

	private:

		/**
		*   Return backbufer.
		*/
		LPDIRECT3DSURFACE9 GetBackBuffer();

		/**
		*   Return z buffer.
		*/
		LPDIRECT3DSURFACE9 GetZBuffer();

		/**
		*   Constructor.
		*/
		DXRenderWindow(Direct3DGlobals* direct3d);

		/**
		*   Object based callback for WindowProcedure.
		*/
		LRESULT OnMessage (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

		/**
		*   Win32 API Window procedure.
		*/
		static LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

		/**
		*   Reset window to new pos/size.
		*/
		void MovedOrResized();

		/**
		*   Update targets content (render).
		*/
		virtual void Update(void);

		/**
		*   Create (or recreate) the D3D device or SwapChain for this window.
		*/
		void CreateD3DResources();

		/**
		*   Destroy the D3D device or SwapChain for this window.
		*/
		void DestroyD3DResources();

		/**
		*   Update depth buffer.
		*/
		void UpdateZBuffer();

	private:

		HWND m_hWnd;

		D3DPRESENT_PARAMETERS m_d3dPresentParams;

		ComPtr<IDirect3DSwapChain9> m_swapChain;

		ComPtr<IDirect3DSurface9> m_renderSurface;

		ComPtr<IDirect3DSurface9> m_renderZBuffer;

		Direct3DGlobals* m_direct3d;

		bool m_isSwapChain;

		unsigned int m_width;
		unsigned int m_height;
	};
}

#endif
